#ifndef __SPEAKER_LED_H
#define __SPEAKER_LED_H

#include <rclcpp/rclcpp.hpp> 
#include <std_msgs/msg/u_int32_multi_array.hpp>
#include <std_msgs/msg/string.hpp>
#include "ubt_speaker_led/node.h"

#define VOLUMEDEFAULT 100 // 音量默认值
#define LOWPERPOWER   20  // 电量低于20%播报语音 yyy 2020-9-18 v3.0.4

//语音选择
enum e_VoiceSelect
{
    power_on            = 1,  // 欢迎使用瓦力智能移动机器人
    power_off           = 2,  // 我要关机了
    stop_btn            = 3,  // 急停按钮已按下
    stop_bar            = 4,  // 防撞条已触发
    dis_net             = 5,  // 网络已断开
    con_net             = 6,  // 网络已连接(mqtt两者均连接上)
    dis_bt              = 7,  // 蓝牙已断开
    con_bt              = 8,  // 蓝牙已连接
    start_charge        = 9,  // 正在充电
    wifi_config_succeed = 10, // 网络配置成功
    wifi_config_fail    = 11, // 网络配置失败
    power_limit         = 12, // 电量过低，强制关机
    unload_material     = 13, // 请取走物料
    load_material       = 14, // 请配送物料
    location_succeed    = 15, // 定位成功
    out_meter_fail      = 16, // 任务无法执行，请将我移动至路网附近
    power_lower         = 17, // 电量过低，我要去充电了
    start_recharge      = 18, // 我要去充电了
    recharge_fail       = 19, // 回充失败请检查
    alarm_area          = 20, // 请注意避让
    obstacleing         = 21, // 避障中，请移走障碍物
    nrefault_state      = 22, // 机器发生故障，请检查
    task_cancel         = 23, // 任务已被取消
    task_pause          = 24, // 任务已被暂停
    task_pause_run      = 25, // 我要继续执行任务了
    task_run            = 26, // 我要去执行任务了
    location_lose       = 27, // 定位丢失，请检查
    location_fail       = 28, // 定位失败，请重新为我定位
    navigation_fail     = 29, // 导航失败，请检查
    move_next_station   = 30, // 前往下一个目标点
    obstacle_timeout    = 31, // 避障超时，请检查
    joystick_connect    = 32, // 遥控手柄已连接
    joystick_disconnect = 33, // 遥控手柄已断开
    release_btn         = 34, // 解抱闸，可以移动了
    rotate_left         = 35, // 向左转时
    rotate_right        = 36, // 向右转时
    start_map           = 37, // 开始建图
    end_map             = 38, // 结束建图
    task_action         = 39, // 执行动作（包含顶升、牵引、举升)
    auto_find           = 40, // 开始寻线，请注意。
    wait_resp           = 41, // 等待响应
};

enum State_Machine
{
    INIT = 0,
    TROUBLE,
    COLLISION,
    BRAKE,
    BTNSTOP,
    OBSTACLE,
    WAIT,
    RUN,
    LOWER,
    CHARGE_FULL,
    CHARGE,
    PAUSE,
    ROTATELEFT,
    ROTATERIGHT,
    INITPOSE,
    NREFAULT,
    REFAULT,
    DEFAULT
};

enum Speak_State
{
    NOTALLOWSPEAK,
    ALLOWSPEAK,
    WAITSPEAK
};

enum Led_mode
{
    MODE_STATIC = 1,    // 静态(常亮)
    MODE_BREATHE,       // 呼吸
    MODE_BLINK,         // 闪烁
    MODE_FLOW,          // 流水(全部，包括左右)
    MODE_FLOW_LEFT,     // 左流水
    MODE_FLOW_RIGHT,    // 右流水
};

#pragma pack(1)
typedef struct
{
    void* data;         // 检测的数据
    int bit;            // 位数：-1代表检测的是整数，0-n代表检测字节中的某一位
    char targetval;     // 期望的目标值
    int voice;          // 播报的语音
    int delay;       // 播报的延时时间
    bool clear;         // 是否清除检测的数据
    bool firstnotspeak; // 第一次不播报--刚开机可能导致一直播报
    bool ignorerepeat;  // 重复时忽略，只有改变data值后才做操作

} t_VoiceSelect;
typedef struct
{
    void* data;         // 检测的数据
    int bit;            // 位数：-1代表检测的是整数，0-n代表检测字节中的某一位
    char targetval;     // 期望的目标值
    int voice;          // 播报的语音
    int loop_times;     // 循环次数-只在循环数组中有效
    int time_separate;  // 每次循环的时间间隔
} t_VoiceSelect_loop;

typedef struct
{
    State_Machine state;
    void* data;
    int bit;
    char targetval;
    void (*callback)(void);
} t_LedSelect;
#pragma pack(0)

class Speaker_Led
{
private:
    Speaker_Led();
    ~Speaker_Led();

    static Speaker_Led* instance;

public:
    unsigned char netstatus;   // 网络状态，(mqtt 和 WiFi 连接状态), 0: 两者都没有连接，1： wifi连接/mqtt 连接， 2：两者都连接
    unsigned char perpower;
    unsigned char ubtstate;

    unsigned char pbstatus;    // 电源状态 1：on， 0：off
    unsigned char blestatus;   // 蓝牙连接状态 0：断开，1：连接
    unsigned char emergency_;  // 急停
    unsigned char collision_;  // 防撞条
    unsigned char brake_;      //解抱闸
    unsigned char trouble;
    unsigned char wificonfig;
    unsigned char wifistatus;  // wifi 网络连接状态 0：未连接，1：连接
    unsigned char mqttstatus;  // mqtt 连接状态     1：连接， 2：未连接
    unsigned char lowerpower;
    unsigned char chargestatus;
    unsigned char chargefull;
    unsigned char rotatestatus;
    unsigned char rotatestatus_voice; //
    unsigned char defaultdata;
    unsigned char speakeraction;
    unsigned char initposestatus;
    unsigned char obstaclealarm;
    unsigned char joystickconnect;
    unsigned char navspeedlimit;
    unsigned int processstate;
    unsigned char mapstatus;//建图状态
    unsigned char autoFindState;//自动巡线状态
    unsigned char actionWarn;//执行任务动作时触发子任务（包含顶升、牵引、举升）
    unsigned char task_start_pause;

    int g_Limit_Power;
    bool b_Speak_Allow;
    
    double d_Speak_Allow_Times;
    int g_VoiceVolume;

    

    rclcpp::Publisher<std_msgs::msg::UInt32MultiArray>::SharedPtr voice_ctl_pub;
    rclcpp::Publisher<std_msgs::msg::UInt32MultiArray>::SharedPtr led_ctl_pub;

    int old_voice;
    int repeat_count;//重复的语音次数，重复一次3s,对应main.cpp中设置的ros::Duration(3).sleep();

    static Speaker_Led* Instance()
    {
        return instance;
    }

    /*播放器控制*/
    void Speaker_Ctrl(int voice, int volume);

    /*led控制*/
    void Led_Ctrl(const std_msgs::msg::UInt32MultiArray &led_msg);

    void Led_Update();
    void Speaker_Update();
    bool Get_Bit(int data, char bit);

    // 更新网络状态
    void Update_net_status();
};

#endif

